package com.usdt.system.service.impl.cp;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usdt.common.core.domain.entity.SysDictData;
import com.usdt.common.core.domain.entity.SysUser;
import com.usdt.common.exception.ServiceException;
import com.usdt.common.utils.bean.BeanUtil;
import com.usdt.system.cp.utils.UserAndDeptUtils;
import com.usdt.system.domain.req.ConditionReqVO;
import com.usdt.system.domain.resp.BatchClueRespVO;
import com.usdt.system.domain.resp.BatchVisitRespVO;
import com.usdt.system.domain.resp.ProjectScopRespVO;
import com.usdt.system.domain.resp.SaleUserDetailsExportRespVO;
import com.usdt.system.domain.resp.SaleUserDetailsRespVO;
import com.usdt.system.domain.resp.SalesCountRespVO;
import com.usdt.system.domain.resp.SalesDataRespVO;
import com.usdt.system.domain.resp.SalesUserMonthCountRespVO;
import com.usdt.system.domain.resp.SalesUserMonthDataDetailsRespVO;
import com.usdt.system.domain.resp.SalesUserMonthDataRespVO;
import com.usdt.system.domain.resp.SignUserRespVo;
import com.usdt.system.dto.cp.ClueUserExcelDTO;
import com.usdt.system.dto.cp.SignSourceExcelDTO;
import com.usdt.system.dto.cp.SignUserExcelDTO;
import com.usdt.system.dto.cp.VisitUserExcelDTO;
import com.usdt.system.mapper.cp.SalesCountMapper;
import com.usdt.system.service.ISysDictTypeService;
import com.usdt.system.service.ISysUserService;
import com.usdt.system.service.cp.AsyncService;
import com.usdt.system.service.cp.SalesCountService;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class SalesCountServiceImpl implements SalesCountService {

	private static final Integer Sales_Person_Id = 101;

	@Value("${sys.properties.ky.main_dept_id}")
	public String mainDeptId;

	@Autowired
	private SalesCountMapper salesCountMapper;

	@Autowired
	private ISysUserService userService;

	@Autowired
	private ISysDictTypeService dictTypeService;

	@Autowired
	private AsyncService asyncService;

	@Override
	public List<ProjectScopRespVO> projectScop() {
		List<ProjectScopRespVO> result = new ArrayList<ProjectScopRespVO>();

		List<SysDictData> projectData = dictTypeService.selectDictDataByType("project_manage");
		SysUser sysUser = userService.selectUserByCpId(UserAndDeptUtils.getCurrentUserId());
		List<String> deptList = Arrays.stream(sysUser.getCpDeptId().split(",")).collect(Collectors.toList());
		if (!CollectionUtils.isEmpty(deptList)) {
			for (String deptId : deptList) {
				SysDictData pro = projectData.stream().filter(e -> deptId.equals(e.getDictValue())).findAny()
						.orElse(null);
				ProjectScopRespVO respVo = new ProjectScopRespVO();
				respVo.setDeptId(deptId);
				respVo.setDeptName(pro.getDictLabel());
				result.add(respVo);
			}
		}
		return result;
	}

	@Override
	public SalesCountRespVO getClueUserCount(String startDate, String endDate, List<String> deptIds) {
		SalesCountRespVO result = new SalesCountRespVO();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		List<SalesDataRespVO> salesDataRespVOList = salesCountMapper.getClueUserCount(startDate, endDate, deptIds);
		result.setSalesDataList(
				CollectionUtils.isEmpty(salesDataRespVOList) ? new ArrayList<SalesDataRespVO>() : salesDataRespVOList);
		return result;
	}

	@Override
	public IPage<BatchClueRespVO> getClueUserData(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		
		Map<String, String> map = this.parseParem(conditions);
		return salesCountMapper.getClueUserData(new Page<>(pageNum, pageSize), startDate, endDate, deptIds, id,map.get("param1"),map.get("param2"));
	}
	
	@Override
	public List<ClueUserExcelDTO> getClueUserDataExport(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		List<ClueUserExcelDTO> result = new ArrayList<ClueUserExcelDTO>();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		
		//Map<String, String> map = this.parseParem(conditions);
		Map<String, String> map = new HashMap<String, String>();
		List<BatchClueRespVO> clueUserData = salesCountMapper.getClueUserDataExport(startDate, endDate, deptIds, id,map.get("param1"),map.get("param2"));
		
		if(!CollectionUtils.isEmpty(clueUserData)) {
			//性别 sys_user_sex
			List<SysDictData> sysUserSex = dictTypeService.selectDictDataByType("sys_user_sex");
			//项目 project_manage
			List<SysDictData> projectManage = dictTypeService.selectDictDataByType("project_manage");
			//线索级别 clue_level
			List<SysDictData> clueLevel = dictTypeService.selectDictDataByType("clue_level");
			//线索来源 clue_source
			List<SysDictData> clueSource = dictTypeService.selectDictDataByType("clue_source");
			for (BatchClueRespVO batchClueRespVO : clueUserData) {
				ClueUserExcelDTO bean = BeanUtil.toBean(batchClueRespVO,ClueUserExcelDTO.class);
				bean.setSex(sysUserSex.stream().filter(e -> e.getDictValue().equals(batchClueRespVO.getSex())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setDeptName(projectManage.stream().filter(e -> e.getDictValue().equals(batchClueRespVO.getDeptId())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setLevel(clueLevel.stream().filter(e -> e.getDictValue().equals(batchClueRespVO.getLevel())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setSource(clueSource.stream().filter(e -> e.getDictValue().equals(batchClueRespVO.getSource())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				result.add(bean);
			}
		}
		return result;
	}

	/**解析查询条件
	 * @param conditions
	 * @param i
	 * @return
	 */
	private Map<String, String> parseParem(String conditions) {
		Map<String, String> map = new HashMap<String, String>();
		String param1 = "";//外层条件
		String param2 = "";//内层条件 客户条件
		if(StringUtils.isBlank(conditions)) {
			return map;
		}
		List<ConditionReqVO> conditionList = JSON.parseArray(conditions, ConditionReqVO.class);
		for (ConditionReqVO conditionReqVO : conditionList) {
			String field = conditionReqVO.getField();
			String operator = conditionReqVO.getOperator();
			List<Object> value = conditionReqVO.getValue();
			if("source".equals(field)) {
				param1 = param1 + " and b.source='"+value.get(0)+"'";
			}
			if("level".equals(field)) {
				param1 = param1 + " and b.level='"+value.get(0)+"'";
			}
			if("sex".equals(field)) {
				param2 = param2 + " and scci.sex='"+value.get(0)+"'";
			}
			if("age".equals(field)) {
				if(null!=value.get(0)) {
					param2 = param2 + " and scci.age>="+value.get(0);
				}
				if(null!=value.get(1)) {
					param2 = param2 + " and scci.age<="+value.get(1);
				}
			}
			if("name".equals(field)) {
				if("EQUALS".equals(operator)) {
					param2 = param2 + " and scci.name='"+value.get(0)+"'";
				}
				if("CONTAIN".equals(operator)) {
					param2 = param2 + " and scci.name like '%"+value.get(0)+"%'";
				}
			}
			if("phoneNumber".equals(field)) {
				if("EQUALS".equals(operator)) {
					param2 = param2 + " and scci.phone_number='"+value.get(0)+"'";
				}
				if("CONTAIN".equals(operator)) {
					param2 = param2 + " and scci.phone_number like '%"+value.get(0)+"%'";
				}
			}
			if("clueTime".equals(field)) {
				if(null!=value.get(0)) {
					param1 = param1 + " and b.clueTime>='"+value.get(0)+"'";
				}
				if(null!=value.get(1)) {
					param1 = param1 + " and b.clueTime<='"+value.get(1)+"'";
				}
			}
			if("salespersonName".equals(field)) {
				if("EQUALS".equals(operator)) {
					param1 = param1 + " and b.salespersonName='"+value.get(0)+"'";
				}
				if("CONTAIN".equals(operator)) {
					param1 = param1 + " and b.salespersonName like '%"+value.get(0)+"%'";
				}
			}
			if("deptId".equals(field)) {
				param1 = param1 + " and b.deptId='"+value.get(0)+"'";
			}
			if("lastFollowUpTime".equals(field)) {
				if(null!=value.get(0)) {
					param1 = param1 + " and b.lastFollowUpTime>='"+value.get(0)+"'";
				}
				if(null!=value.get(1)) {
					param1 = param1 + " and b.lastFollowUpTime<='"+value.get(1)+"'";
				}
			}
			if("customerStatus".equals(field)) {
				param1 = param1 + " and b.customerStatus='"+value.get(0)+"'";
			}
			if("clueSource".equals(field)) {
				param1 = param1 + " and b.clueSource='"+value.get(0)+"'";
			}
			if("visitTime".equals(field)) {
				if(null!=value.get(0)) {
					param1 = param1 + " and b.visitTime>='"+value.get(0)+"'";
				}
				if(null!=value.get(1)) {
					param1 = param1 + " and b.visitTime<='"+value.get(1)+"'";
				}
			}
			if("lastVisitTime".equals(field)) {
				if(null!=value.get(0)) {
					param1 = param1 + " and b.lastVisitTime>='"+value.get(0)+"'";
				}
				if(null!=value.get(1)) {
					param1 = param1 + " and b.lastVisitTime<='"+value.get(1)+"'";
				}
			}
			if("lastCallbackTime".equals(field)) {
				if(null!=value.get(0)) {
					param1 = param1 + " and b.lastCallbackTime>='"+value.get(0)+"'";
				}
				if(null!=value.get(1)) {
					param1 = param1 + " and b.lastCallbackTime<='"+value.get(1)+"'";
				}
			}
			
		}
		
		map.put("param1", param1);
		map.put("param2", param2);
		return map;
	}

	@Override
	public SalesCountRespVO getVisitUserCount(String startDate, String endDate, List<String> deptIds) {
		SalesCountRespVO result = new SalesCountRespVO();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		List<SalesDataRespVO> salesDataRespVOList = salesCountMapper.getVisitUserCount(startDate, endDate, deptIds);
		result.setSalesDataList(
				CollectionUtils.isEmpty(salesDataRespVOList) ? new ArrayList<SalesDataRespVO>() : salesDataRespVOList);
		return result;
	}

	@Override
	public IPage<BatchVisitRespVO> getVisitUserData(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		
		Map<String, String> map = this.parseParem(conditions);
		return salesCountMapper.getVisitUserData(new Page<>(pageNum, pageSize), startDate, endDate, deptIds, id,map.get("param1"),map.get("param2"));
	}
	
	@Override
	public List<VisitUserExcelDTO> getVisitUserDataExport(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		List<VisitUserExcelDTO> result= new ArrayList<VisitUserExcelDTO>();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		
		//Map<String, String> map = this.parseParem(conditions);
		Map<String, String> map = new HashMap<String, String>();
		List<BatchVisitRespVO> visitUserData = salesCountMapper.getVisitUserDataExport(startDate, endDate, deptIds, id,map.get("param1"),map.get("param2"));
		if(!CollectionUtils.isEmpty(visitUserData)) {
			//性别 sys_user_sex
			List<SysDictData> sysUserSex = dictTypeService.selectDictDataByType("sys_user_sex");
			//项目 project_manage
			List<SysDictData> projectManage = dictTypeService.selectDictDataByType("project_manage");
			//客户状态 visit_customer_status
			List<SysDictData> visitCustomerStatus = dictTypeService.selectDictDataByType("visit_customer_status");
			//线索来源 clue_source
			List<SysDictData> clueSource = dictTypeService.selectDictDataByType("clue_source");
			for (BatchVisitRespVO batchVisitRespVO : visitUserData) {
				VisitUserExcelDTO bean = BeanUtil.toBean(batchVisitRespVO,VisitUserExcelDTO.class);
				bean.setSex(sysUserSex.stream().filter(e -> e.getDictValue().equals(batchVisitRespVO.getSex())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setDeptName(projectManage.stream().filter(e -> e.getDictValue().equals(batchVisitRespVO.getDeptId())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setCustomerStatus(visitCustomerStatus.stream().filter(e -> e.getDictValue().equals(batchVisitRespVO.getCustomerStatus())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setClueSource(clueSource.stream().filter(e -> e.getDictValue().equals(batchVisitRespVO.getClueSource())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				result.add(bean);
			}
		}
		
		return result;
	}

	@Override
	public SalesCountRespVO getClueSourceCount(String startDate, String endDate, List<String> deptIds) {
		SalesCountRespVO result = new SalesCountRespVO();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		List<SalesDataRespVO> salesDataRespVOList = salesCountMapper.getClueSourceCount(startDate, endDate, deptIds);
		result.setSalesDataList(
				CollectionUtils.isEmpty(salesDataRespVOList) ? new ArrayList<SalesDataRespVO>() : salesDataRespVOList);
		return result;
	}

	@Override
	public IPage<BatchClueRespVO> getClueSourceData(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}

		Map<String, String> map = this.parseParem(conditions);
		return salesCountMapper.getClueSourceData(new Page<>(pageNum, pageSize), startDate, endDate, deptIds, id,map.get("param1"),map.get("param2"));
	}
	
	@Override
	public List<ClueUserExcelDTO> getClueSourceDataExport(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		List<ClueUserExcelDTO> result = new ArrayList<ClueUserExcelDTO> ();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		
		//Map<String, String> map = this.parseParem(conditions);
		Map<String, String> map = new HashMap<>();
		List<BatchClueRespVO> clueSourceData = salesCountMapper.getClueSourceDataExport(startDate, endDate, deptIds, id,map.get("param1"),map.get("param2"));
		if(!CollectionUtils.isEmpty(clueSourceData)) {
			//性别 sys_user_sex
			List<SysDictData> sysUserSex = dictTypeService.selectDictDataByType("sys_user_sex");
			//项目 project_manage
			List<SysDictData> projectManage = dictTypeService.selectDictDataByType("project_manage");
			//线索级别 clue_level
			List<SysDictData> clueLevel = dictTypeService.selectDictDataByType("clue_level");
			//线索来源 clue_source
			List<SysDictData> clueSource = dictTypeService.selectDictDataByType("clue_source");
			for (BatchClueRespVO batchClueRespVO : clueSourceData) {
				ClueUserExcelDTO bean = BeanUtil.toBean(batchClueRespVO,ClueUserExcelDTO.class);
				bean.setSex(sysUserSex.stream().filter(e -> e.getDictValue().equals(batchClueRespVO.getSex())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setDeptName(projectManage.stream().filter(e -> e.getDictValue().equals(batchClueRespVO.getDeptId())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setLevel(clueLevel.stream().filter(e -> e.getDictValue().equals(batchClueRespVO.getLevel())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setSource(clueSource.stream().filter(e -> e.getDictValue().equals(batchClueRespVO.getSource())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				result.add(bean);
			}
		}
		
		return result;
	}

	@Override
	public SalesCountRespVO getVisitSourceCount(String startDate, String endDate, List<String> deptIds) {
		SalesCountRespVO result = new SalesCountRespVO();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		List<SalesDataRespVO> salesDataRespVOList = salesCountMapper.getVisitSourceCount(startDate, endDate, deptIds);
		result.setSalesDataList(
				CollectionUtils.isEmpty(salesDataRespVOList) ? new ArrayList<SalesDataRespVO>() : salesDataRespVOList);
		return result;
	}

	@Override
	public IPage<BatchVisitRespVO> getVisitSourceData(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		Map<String, String> map = this.parseParem(conditions);
		return salesCountMapper.getVisitSourceData(new Page<>(pageNum, pageSize), startDate, endDate, deptIds, id,map.get("param1"),map.get("param2"));
	}
	
	@Override
	public List<VisitUserExcelDTO> getVisitSourceDataExport(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		List<VisitUserExcelDTO> result= new ArrayList<VisitUserExcelDTO>();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		//Map<String, String> map = this.parseParem(conditions);
		Map<String, String> map = new HashMap<String, String>();
		List<BatchVisitRespVO> visitSourceData = salesCountMapper.getVisitSourceDataExport(startDate, endDate, deptIds, id,map.get("param1"),map.get("param2"));
		if(!CollectionUtils.isEmpty(visitSourceData)) {
			//性别 sys_user_sex
			List<SysDictData> sysUserSex = dictTypeService.selectDictDataByType("sys_user_sex");
			//项目 project_manage
			List<SysDictData> projectManage = dictTypeService.selectDictDataByType("project_manage");
			//客户状态 visit_customer_status
			List<SysDictData> visitCustomerStatus = dictTypeService.selectDictDataByType("visit_customer_status");
			//线索来源 clue_source
			List<SysDictData> clueSource = dictTypeService.selectDictDataByType("clue_source");
			for (BatchVisitRespVO batchVisitRespVO : visitSourceData) {
				VisitUserExcelDTO bean = BeanUtil.toBean(batchVisitRespVO,VisitUserExcelDTO.class);
				bean.setSex(sysUserSex.stream().filter(e -> e.getDictValue().equals(batchVisitRespVO.getSex())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setDeptName(projectManage.stream().filter(e -> e.getDictValue().equals(batchVisitRespVO.getDeptId())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setCustomerStatus(visitCustomerStatus.stream().filter(e -> e.getDictValue().equals(batchVisitRespVO.getCustomerStatus())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				bean.setClueSource(clueSource.stream().filter(e -> e.getDictValue().equals(batchVisitRespVO.getClueSource())).findAny()
						.orElse(new SysDictData()).getDictLabel());
				result.add(bean);
			}
		}
		
		return result;
	}

	@Override
	public SalesCountRespVO getSignUserCount(String startDate, String endDate, List<String> deptIds) {
		SalesCountRespVO result = new SalesCountRespVO();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return result;
		}
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return result;
		}
		Map<String, List<SignUserRespVo>> map = signUserList.stream()
				.collect(Collectors.groupingBy(SignUserRespVo::getUserId));
		List<SalesDataRespVO> salesDataList = new ArrayList<SalesDataRespVO>();
		map.forEach((k, v) -> {
			SalesDataRespVO salesData = new SalesDataRespVO();
			salesData.setCount(v.size());
			salesData.setName(v.get(0).getUserName());
			salesData.setId(k);
			salesData.setRate(new BigDecimal(v.size()).multiply(new BigDecimal(100))
					.divide(new BigDecimal(signUserList.size()), 2, RoundingMode.HALF_UP));
			salesDataList.add(salesData);
		});
		result.setSalesDataList(salesDataList);
		return result;
	}

	@Override
	public IPage<SignUserRespVo> getSignUserData(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		IPage page = new Page();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return page;
		}
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return page;
		}
		
		// 填充项目
		List<SysDictData> projectData = dictTypeService.selectDictDataByType("project_manage");
		for (SignUserRespVo signUserRespVo : signUserList) {
			SysDictData sysDictData = projectData.stream()
					.filter(e -> signUserRespVo.getDeptId().equals(e.getDictValue())).findAny().orElse(null);
			signUserRespVo.setDeptName(null == sysDictData ? null : sysDictData.getDictLabel());
			
			//渠道
			if (StringUtils.isBlank(signUserRespVo.getPhoneNumber())) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			SalesDataRespVO salesDataRespVO = salesCountMapper
					.getSourceByPhoneNumberAndDeptId(signUserRespVo.getPhoneNumber(), signUserRespVo.getDeptId());
			if (null == salesDataRespVO) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			signUserRespVo.setSourceId(salesDataRespVO.getId());
			signUserRespVo.setSourceName(salesDataRespVO.getName());
		}
		
		//解析查询条件
		signUserList = this.parseSignParem(conditions,signUserList);
		
		Map<String, List<SignUserRespVo>> map = signUserList.stream()
				.collect(Collectors.groupingBy(SignUserRespVo::getUserId));
		List<SignUserRespVo> list =CollectionUtils.isEmpty(map.get(id))? new ArrayList<SignUserRespVo>():map.get(id);

		list.sort((SignUserRespVo v1, SignUserRespVo v2) -> {
			int compareTo = v2.getStartDate().compareTo(v1.getStartDate());
			if (0 == compareTo) {
				return v2.getCustomerId().compareTo(v2.getCustomerId());
			}
			return v2.getStartDate().compareTo(v1.getStartDate());
		});

		List<SignUserRespVo> collect = list.stream().skip((pageNum - 1) * pageSize).limit(pageSize)
				.collect(Collectors.toList());
		
		page.setRecords(collect);
		page.setCurrent(pageNum);
		page.setSize(pageSize);
		page.setTotal(list.size());
		return page;
	}
	
	@Override
	public List<SignUserExcelDTO> getSignUserDataExport(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		List<SignUserExcelDTO> result = new ArrayList<SignUserExcelDTO>();
		
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return result;
		}
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return result;
		}
		// 填充项目
		List<SysDictData> projectData = dictTypeService.selectDictDataByType("project_manage");
		for (SignUserRespVo signUserRespVo : signUserList) {
			SysDictData sysDictData = projectData.stream()
					.filter(e -> signUserRespVo.getDeptId().equals(e.getDictValue())).findAny().orElse(null);
			signUserRespVo.setDeptName(null == sysDictData ? null : sysDictData.getDictLabel());
			
			//渠道
			if (StringUtils.isBlank(signUserRespVo.getPhoneNumber())) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			SalesDataRespVO salesDataRespVO = salesCountMapper
					.getSourceByPhoneNumberAndDeptId(signUserRespVo.getPhoneNumber(), signUserRespVo.getDeptId());
			if (null == salesDataRespVO) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			signUserRespVo.setSourceId(salesDataRespVO.getId());
			signUserRespVo.setSourceName(salesDataRespVO.getName());
		}
				
		//解析查询条件
		signUserList = this.parseSignParem(null,signUserList);
		
		Map<String, List<SignUserRespVo>> map = signUserList.stream()
				.collect(Collectors.groupingBy(SignUserRespVo::getUserId));
		List<SignUserRespVo> list =CollectionUtils.isEmpty(map.get(id))? new ArrayList<SignUserRespVo>():map.get(id);
		
		list.sort((SignUserRespVo v1, SignUserRespVo v2) -> {
			int compareTo = v2.getStartDate().compareTo(v1.getStartDate());
			if (0 == compareTo) {
				return v2.getCustomerId().compareTo(v2.getCustomerId());
			}
			return v2.getStartDate().compareTo(v1.getStartDate());
		});
		
		/*List<SignUserRespVo> collect = list.stream().skip((pageNum - 1) * pageSize).limit(pageSize)
				.collect(Collectors.toList());*/
		
		return BeanUtil.toBeans(list, SignUserExcelDTO.class);
	}

	/**首签数据拼接
	 * @param conditions
	 * @param signUserList
	 */
	private List<SignUserRespVo> parseSignParem(String conditions, List<SignUserRespVo> signUserList) {
		List<SignUserRespVo> result = signUserList;
		if(StringUtils.isBlank(conditions)) {
			return result;
		}
		List<ConditionReqVO> conditionList = JSON.parseArray(conditions, ConditionReqVO.class);
		for (ConditionReqVO conditionReqVO : conditionList) {
			List<SignUserRespVo> tempList = new ArrayList<SignUserRespVo>();
			String field = conditionReqVO.getField();
			String operator = conditionReqVO.getOperator();
			List<Object> value = conditionReqVO.getValue();
			
			for (SignUserRespVo signUserRespVo : result) {
				if("customerName".equals(field)) {
					String customerName = signUserRespVo.getCustomerName();
					if(StringUtils.isBlank(customerName)) {
						continue;
					}
					if("EQUALS".equals(operator)) {
						if(((String)value.get(0)).equals(customerName)) {
							tempList.add(signUserRespVo);
						}
					}
					if("CONTAIN".equals(operator)) {
						if(customerName.contains((String)value.get(0))) {
							tempList.add(signUserRespVo);
						}
					}
				}
				if("age".equals(field)) {
					Integer age = signUserRespVo.getAge();
					if(null==age) {
						continue;
					}
					boolean bo=true;
					if(null!=value.get(0)) {
						if(!((Integer)value.get(0)<=age)) {
							bo=false;
						}
					}
					if(null!=value.get(1)) {
						if(!((Integer)value.get(1)>=age)) {
							bo=false;
						}
					}
					if(bo) {
						tempList.add(signUserRespVo);
					}
				}
				if("sex".equals(field)) {
					String sex = signUserRespVo.getSex();
					if(StringUtils.isBlank(sex)) {
						continue;
					}
					if(((String)value.get(0)).equals(sex)) {
						tempList.add(signUserRespVo);
					}
				}
				if("phoneNumber".equals(field)) {
					String phoneNumber = signUserRespVo.getPhoneNumber();
					if(StringUtils.isBlank(phoneNumber)) {
						continue;
					}
					if("EQUALS".equals(operator)) {
						if(((String)value.get(0)).equals(phoneNumber)) {
							tempList.add(signUserRespVo);
						}
					}
					if("CONTAIN".equals(operator)) {
						if(phoneNumber.contains((String)value.get(0))) {
							tempList.add(signUserRespVo);
						}
					}
				}
				if("signDate".equals(field)) {
					String signDate = signUserRespVo.getSignDate();
					if(StringUtils.isBlank(signDate)) {
						continue;
					}
					boolean bo=true;
					if(null!=value.get(0)) {
						if(!(((String)value.get(0)).compareTo(signDate)<=0)) {
							bo=false;
						}
					}
					if(null!=value.get(1)) {
						if(!(((String)value.get(1)).compareTo(signDate)>=0)) {
							bo=false;
						}
					}
					if(bo) {
						tempList.add(signUserRespVo);
					}
				}
				if("contractStatus".equals(field)) {
					String contractStatus = signUserRespVo.getContractStatus();
					if(StringUtils.isBlank(contractStatus)) {
						continue;
					}
					if(((String)value.get(0)).equals(contractStatus)) {
						tempList.add(signUserRespVo);
					}
				}
				if("startDate".equals(field)) {
					String startDate = signUserRespVo.getStartDate();
					if(StringUtils.isBlank(startDate)) {
						continue;
					}
					boolean bo=true;
					if(null!=value.get(0)) {
						if(!(((String)value.get(0)).compareTo(startDate)<=0)) {
							bo=false;
						}
					}
					if(null!=value.get(1)) {
						if(!(((String)value.get(1)).compareTo(startDate)>=0)) {
							bo=false;
						}
					}
					if(bo) {
						tempList.add(signUserRespVo);
					}
				}
				if("endDate".equals(field)) {
					String endDate = signUserRespVo.getEndDate();
					if(StringUtils.isBlank(endDate)) {
						continue;
					}
					boolean bo=true;
					if(null!=value.get(0)) {
						if(!(((String)value.get(0)).compareTo(endDate)<=0)) {
							bo=false;
						}
					}
					if(null!=value.get(1)) {
						if(!(((String)value.get(1)).compareTo(endDate)>=0)) {
							bo=false;
						}
					}
					if(bo) {
						tempList.add(signUserRespVo);
					}
				}
				if("userName".equals(field)) {
					String userName = signUserRespVo.getUserName();
					if(StringUtils.isBlank(userName)) {
						continue;
					}
					if("EQUALS".equals(operator)) {
						if(((String)value.get(0)).equals(userName)) {
							tempList.add(signUserRespVo);
						}
					}
					if("CONTAIN".equals(operator)) {
						if(userName.contains((String)value.get(0))) {
							tempList.add(signUserRespVo);
						}
					}
				}
				if("deptId".equals(field)) {
					String deptId = signUserRespVo.getDeptId();
					if(StringUtils.isBlank(deptId)) {
						continue;
					}
					if(((String)value.get(0)).equals(deptId)) {
						tempList.add(signUserRespVo);
					}
				}
				if("deptName".equals(field)) {
					String deptName = signUserRespVo.getDeptName();
					if(StringUtils.isBlank(deptName)) {
						continue;
					}
					if(((String)value.get(0)).equals(deptName)) {
						tempList.add(signUserRespVo);
					}
				}
				if("sourceId".equals(field)) {
					String sourceId = signUserRespVo.getSourceId();
					if(StringUtils.isBlank(sourceId)) {
						continue;
					}
					if(((String)value.get(0)).equals(sourceId)) {
						tempList.add(signUserRespVo);
					}
				}
				if("sourceName".equals(field)) {
					String sourceName = signUserRespVo.getSourceName();
					if(StringUtils.isBlank(sourceName)) {
						continue;
					}
					if(((String)value.get(0)).equals(sourceName)) {
						tempList.add(signUserRespVo);
					}
				}
				
			}
			result = tempList;
		}
		//result.stream().collect(Collectors.toSet()).stream().collect(Collectors.toList())
		return result;
	}

	@Override
	public SalesCountRespVO getSignSourceCount(String startDate, String endDate, List<String> deptIds) {
		SalesCountRespVO result = new SalesCountRespVO();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return result;
		}
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return result;
		}

		// 获取渠道
		for (SignUserRespVo signUserRespVo : signUserList) {
			if (StringUtils.isBlank(signUserRespVo.getPhoneNumber())) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			SalesDataRespVO salesDataRespVO = salesCountMapper
					.getSourceByPhoneNumberAndDeptId(signUserRespVo.getPhoneNumber(), signUserRespVo.getDeptId());
			if (null == salesDataRespVO) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			signUserRespVo.setSourceId(salesDataRespVO.getId());
			signUserRespVo.setSourceName(salesDataRespVO.getName());
		}

		Map<String, List<SignUserRespVo>> map = signUserList.stream()
				.collect(Collectors.groupingBy(SignUserRespVo::getSourceId));
		List<SalesDataRespVO> salesDataList = new ArrayList<SalesDataRespVO>();
		map.forEach((k, v) -> {
			SalesDataRespVO salesData = new SalesDataRespVO();
			salesData.setCount(v.size());
			salesData.setName(v.get(0).getSourceName());
			salesData.setId(k);
			salesData.setRate(new BigDecimal(v.size()).multiply(new BigDecimal(100))
					.divide(new BigDecimal(signUserList.size()), 2, RoundingMode.HALF_UP));
			salesDataList.add(salesData);
		});
		result.setSalesDataList(salesDataList);
		return result;
	}

	@Override
	public IPage<SignUserRespVo> getSignSourceData(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		IPage page = new Page();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return page;
		}
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return page;
		}
		
		// 填充项目
		List<SysDictData> projectData = dictTypeService.selectDictDataByType("project_manage");
		for (SignUserRespVo signUserRespVo : signUserList) {
			SysDictData sysDictData = projectData.stream()
					.filter(e -> signUserRespVo.getDeptId().equals(e.getDictValue())).findAny().orElse(null);
			signUserRespVo.setDeptName(null == sysDictData ? null : sysDictData.getDictLabel());
			
			// 获取渠道
			if (StringUtils.isBlank(signUserRespVo.getPhoneNumber())) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			SalesDataRespVO salesDataRespVO = salesCountMapper
					.getSourceByPhoneNumberAndDeptId(signUserRespVo.getPhoneNumber(), signUserRespVo.getDeptId());
			if (null == salesDataRespVO) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			signUserRespVo.setSourceId(salesDataRespVO.getId());
			signUserRespVo.setSourceName(salesDataRespVO.getName());
		}

		//解析查询条件
		signUserList = this.parseSignParem(conditions,signUserList);
				
		Map<String, List<SignUserRespVo>> map = signUserList.stream()
				.collect(Collectors.groupingBy(SignUserRespVo::getSourceId));
		List<SignUserRespVo> list = map.get(id);

		list.sort((SignUserRespVo v1, SignUserRespVo v2) -> {
			int compareTo = v2.getStartDate().compareTo(v1.getStartDate());
			if (0 == compareTo) {
				return v2.getCustomerId().compareTo(v2.getCustomerId());
			}
			return v2.getStartDate().compareTo(v1.getStartDate());
		});

		List<SignUserRespVo> collect = list.stream().skip((pageNum - 1) * pageSize).limit(pageSize)
				.collect(Collectors.toList());
		page.setRecords(collect);
		page.setCurrent(pageNum);
		page.setSize(pageSize);
		page.setTotal(list.size());
		return page;
	}
	
	@Override
	public List<SignSourceExcelDTO> getSignSourceDataExport(String startDate, String endDate, List<String> deptIds, String id,
			Integer pageNum, Integer pageSize,String conditions) {
		List<SignSourceExcelDTO> result = new ArrayList<SignSourceExcelDTO>();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return result;
		}
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return result;
		}
		
		// 填充项目
		List<SysDictData> projectData = dictTypeService.selectDictDataByType("project_manage");
		for (SignUserRespVo signUserRespVo : signUserList) {
			SysDictData sysDictData = projectData.stream()
					.filter(e -> signUserRespVo.getDeptId().equals(e.getDictValue())).findAny().orElse(null);
			signUserRespVo.setDeptName(null == sysDictData ? null : sysDictData.getDictLabel());
			
			// 获取渠道
			if (StringUtils.isBlank(signUserRespVo.getPhoneNumber())) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			SalesDataRespVO salesDataRespVO = salesCountMapper
					.getSourceByPhoneNumberAndDeptId(signUserRespVo.getPhoneNumber(), signUserRespVo.getDeptId());
			if (null == salesDataRespVO) {
				signUserRespVo.setSourceId("0");
				signUserRespVo.setSourceName("其他");
				continue;
			}
			signUserRespVo.setSourceId(salesDataRespVO.getId());
			signUserRespVo.setSourceName(salesDataRespVO.getName());
		}
		
		//解析查询条件
		signUserList = this.parseSignParem(null,signUserList);
		
		Map<String, List<SignUserRespVo>> map = signUserList.stream()
				.collect(Collectors.groupingBy(SignUserRespVo::getSourceId));
		List<SignUserRespVo> list = map.get(id);
		
		list.sort((SignUserRespVo v1, SignUserRespVo v2) -> {
			int compareTo = v2.getStartDate().compareTo(v1.getStartDate());
			if (0 == compareTo) {
				return v2.getCustomerId().compareTo(v2.getCustomerId());
			}
			return v2.getStartDate().compareTo(v1.getStartDate());
		});
		
		
		
		/*List<SignUserRespVo> collect = list.stream().skip((pageNum - 1) * pageSize).limit(pageSize)
				.collect(Collectors.toList());*/
		
		return BeanUtil.toBeans(list, SignSourceExcelDTO.class);
	}

	@Override
	public SaleUserDetailsRespVO getUserDetails(String startDate, String endDate, List<String> deptIds) {
		SaleUserDetailsRespVO saleUserDetails = new SaleUserDetailsRespVO();
		
		startDate = startDate + "-01";
		endDate = endDate + "-01";
		LocalDate startDateTemp = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		LocalDate endDateTemp = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		LocalDate lastDayOfMonth = endDateTemp.with(TemporalAdjusters.lastDayOfMonth());
		endDate = lastDayOfMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		try {
			// 启动所有异步任务
			CompletableFuture<List<SalesUserMonthCountRespVO>> future1 = asyncService.getClueUserMonthCount(startDate,
					endDate, deptIds);
			CompletableFuture<List<SalesUserMonthCountRespVO>> future2 = asyncService.getVisitUserMonthCount(startDate,
					endDate, deptIds);
			CompletableFuture<List<SalesUserMonthCountRespVO>> future3 = asyncService.getSignUserMonthCount(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate,
					endDate, deptIds);

			// 等待所有任务完成并合并结果
			CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);
			// 阻塞直到所有任务完成，最多等待5分钟
			allFutures.get(300, TimeUnit.SECONDS);
			// 获取各个任务的结果
			List<SalesUserMonthCountRespVO> result1 = future1.get();
			Map<String, List<SalesUserMonthCountRespVO>> map1 = result1.stream().collect(Collectors.groupingBy(SalesUserMonthCountRespVO::getUserId));
			List<SalesUserMonthCountRespVO> result2 = future2.get();
			Map<String, List<SalesUserMonthCountRespVO>> map2 = result2.stream().collect(Collectors.groupingBy(SalesUserMonthCountRespVO::getUserId));
			List<SalesUserMonthCountRespVO> result3 = future3.get();
			Map<String, List<SalesUserMonthCountRespVO>> map3 = result3.stream().collect(Collectors.groupingBy(SalesUserMonthCountRespVO::getUserId));

			//提取人员
			List<SalesUserMonthCountRespVO> userAll = new ArrayList<SalesUserMonthCountRespVO>();
			userAll.addAll(result1);
			userAll.addAll(result2);
			userAll.addAll(result3);
			ArrayList<SalesUserMonthCountRespVO> users = userAll.stream().collect(
					Collectors.collectingAndThen(
							Collectors.toCollection(()->new TreeSet<SalesUserMonthCountRespVO>(Comparator.comparing(o->o.getUserId()))), 
							ArrayList::new)	
					);
			users.sort((SalesUserMonthCountRespVO s1,SalesUserMonthCountRespVO s2)->s2.getUserId().compareTo(s1.getUserId()));
			//表头
			List<String> heards = new ArrayList<String>();
			heards.add("业务员");
			heards.add("指标维度");
			heards.add("总计");
			LocalDate startDateTemp1 = startDateTemp;
			while (true) {
				if(startDateTemp1.isAfter(endDateTemp)) {
					break;
				}
				heards.add(startDateTemp1.format(DateTimeFormatter.ofPattern("yyyy年MM月")));
				startDateTemp1 = startDateTemp1.plusMonths(1);
			}
			//数据
			List<SalesUserMonthDataRespVO> dataList = new ArrayList<SalesUserMonthDataRespVO>();
			for (SalesUserMonthCountRespVO salesUserMonthCountRespVO : users) {
				SalesUserMonthDataRespVO salesUserMonthData = new SalesUserMonthDataRespVO();
				salesUserMonthData.setUserId(salesUserMonthCountRespVO.getUserId());
				salesUserMonthData.setUserName(salesUserMonthCountRespVO.getUserName());
				
				//线索
				List<SalesUserMonthDataDetailsRespVO> clueList = new ArrayList<SalesUserMonthDataDetailsRespVO>();
				List<SalesUserMonthCountRespVO> list1 = map1.get(salesUserMonthCountRespVO.getUserId());
				list1 = CollectionUtils.isEmpty(list1)?new ArrayList<SalesUserMonthCountRespVO>():list1;
				SalesUserMonthDataDetailsRespVO salesUserMonthDataDetails1 = new SalesUserMonthDataDetailsRespVO(); 
				salesUserMonthDataDetails1.setKey("总计");
				salesUserMonthDataDetails1.setValue(list1.stream().mapToInt(p -> p.getCount()).sum());
				clueList.add(salesUserMonthDataDetails1);
				//到访
				List<SalesUserMonthDataDetailsRespVO> visitList = new ArrayList<SalesUserMonthDataDetailsRespVO>();
				List<SalesUserMonthCountRespVO> list2 = map2.get(salesUserMonthCountRespVO.getUserId());
				list2 = CollectionUtils.isEmpty(list2)?new ArrayList<SalesUserMonthCountRespVO>():list2;
				SalesUserMonthDataDetailsRespVO salesUserMonthDataDetails2 = new SalesUserMonthDataDetailsRespVO(); 
				salesUserMonthDataDetails2.setKey("总计");
				salesUserMonthDataDetails2.setValue(list2.stream().mapToInt(p -> p.getCount()).sum());
				visitList.add(salesUserMonthDataDetails2);
				//首签
				List<SalesUserMonthDataDetailsRespVO> signList = new ArrayList<SalesUserMonthDataDetailsRespVO>();
				List<SalesUserMonthCountRespVO> list3 = map3.get(salesUserMonthCountRespVO.getUserId());
				list3 = CollectionUtils.isEmpty(list3)?new ArrayList<SalesUserMonthCountRespVO>():list3;
				SalesUserMonthDataDetailsRespVO salesUserMonthDataDetails3 = new SalesUserMonthDataDetailsRespVO(); 
				salesUserMonthDataDetails3.setKey("总计");
				salesUserMonthDataDetails3.setValue(list3.stream().mapToInt(p -> p.getCount()).sum());
				signList.add(salesUserMonthDataDetails3);
				
				LocalDate startDateTemp2 = startDateTemp;
				while (true) {
					if(startDateTemp2.isAfter(endDateTemp)) {
						break;
					}
					String format = startDateTemp2.format(DateTimeFormatter.ofPattern("yyyy-MM"));
					String format2 = startDateTemp2.format(DateTimeFormatter.ofPattern("yyyy年MM月"));
					
					//线索
					Map<String, List<SalesUserMonthCountRespVO>> clueMonthMap = list1.stream().collect(Collectors.groupingBy(SalesUserMonthCountRespVO::getMonth));
					List<SalesUserMonthCountRespVO> clueMonth = clueMonthMap.get(format);
					SalesUserMonthDataDetailsRespVO clueMonthDataDetails = new SalesUserMonthDataDetailsRespVO(); 
					clueMonthDataDetails.setKey(format2);
					clueMonthDataDetails.setValue(CollectionUtils.isEmpty(clueMonth)?0:clueMonth.get(0).getCount());
					clueList.add(clueMonthDataDetails);
					
					//到访
					Map<String, List<SalesUserMonthCountRespVO>> visitMonthMap = list2.stream().collect(Collectors.groupingBy(SalesUserMonthCountRespVO::getMonth));
					List<SalesUserMonthCountRespVO> visitMonth = visitMonthMap.get(format);
					SalesUserMonthDataDetailsRespVO visitMonthDataDetails = new SalesUserMonthDataDetailsRespVO(); 
					visitMonthDataDetails.setKey(format2);
					visitMonthDataDetails.setValue(CollectionUtils.isEmpty(visitMonth)?0:visitMonth.get(0).getCount());
					visitList.add(visitMonthDataDetails);
					
					//首签
					Map<String, List<SalesUserMonthCountRespVO>> signMonthMap = list3.stream().collect(Collectors.groupingBy(SalesUserMonthCountRespVO::getMonth));
					List<SalesUserMonthCountRespVO> signMonth = signMonthMap.get(format);
					SalesUserMonthDataDetailsRespVO signMonthDataDetails = new SalesUserMonthDataDetailsRespVO(); 
					signMonthDataDetails.setKey(format2);
					signMonthDataDetails.setValue(CollectionUtils.isEmpty(signMonth)?0:signMonth.get(0).getCount());
					signList.add(signMonthDataDetails);
					
					startDateTemp2=startDateTemp2.plusMonths(1);
				}
				salesUserMonthData.setClueList(clueList);
				salesUserMonthData.setVisitList(visitList);
				salesUserMonthData.setSignList(signList);
				dataList.add(salesUserMonthData);   
			}

			saleUserDetails.setHeards(heards);
			saleUserDetails.setDataList(dataList);
			return saleUserDetails;
		} catch (Exception e) {
			throw new ServiceException(e.getMessage());
		}
	}
	
	@Override
	public SaleUserDetailsExportRespVO getUserDetailsExport(String startDate, String endDate, List<String> deptIds) {
		SaleUserDetailsExportRespVO result = new SaleUserDetailsExportRespVO();
		SaleUserDetailsRespVO userDetails = this.getUserDetails(startDate,endDate,deptIds);
		List<String> heards = new ArrayList<>();
		heards.addAll(userDetails.getHeards());
		result.setHeards(heards);
		
		List<List<Object>> dataList = new ArrayList<List<Object>>();
		result.setDataList(dataList);
		List<SalesUserMonthDataRespVO> datas = userDetails.getDataList();
		datas.forEach(e->{
			List<Object> clueList = new ArrayList<Object>();
			dataList.add(clueList);
			clueList.add(e.getUserName());
			clueList.add("线索登记条数");
			for (SalesUserMonthDataDetailsRespVO salesUserMonthDataDetailsRespVO : e.getClueList()) {
				clueList.add(salesUserMonthDataDetailsRespVO.getValue());
			}
			
			List<Object> visitList = new ArrayList<Object>();
			dataList.add(visitList);
			visitList.add(e.getUserName());
			visitList.add("到访登记条数");
			for (SalesUserMonthDataDetailsRespVO salesUserMonthDataDetailsRespVO : e.getVisitList()) {
				visitList.add(salesUserMonthDataDetailsRespVO.getValue());
			}
			
			List<Object> signList = new ArrayList<Object>();
			dataList.add(signList);
			signList.add(e.getUserName());
			signList.add("首次签约人数");
			for (SalesUserMonthDataDetailsRespVO salesUserMonthDataDetailsRespVO : e.getSignList()) {
				signList.add(salesUserMonthDataDetailsRespVO.getValue());
			}
		});
		return result;
	}

	@Override
	public List<SalesDataRespVO> getSignUserRank(String startDate, String endDate, List<String> deptIds) {
		List<SalesDataRespVO> result = new ArrayList<SalesDataRespVO>();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		startDate = startDate + "-01";
		endDate = endDate + "-01";
		LocalDate startDateTemp = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		LocalDate endDateTemp = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		LocalDate lastDayOfMonth = endDateTemp.with(TemporalAdjusters.lastDayOfMonth());
		endDate = lastDayOfMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return result;
		}
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return result;
		}
		Map<String, List<SignUserRespVo>> map = signUserList.stream()
				.collect(Collectors.groupingBy(SignUserRespVo::getUserId));
		map.forEach((k, v) -> {
			SalesDataRespVO salesData = new SalesDataRespVO();
			salesData.setCount(v.size());
			salesData.setName(v.get(0).getUserName());
			salesData.setId(k);
			salesData.setRate(new BigDecimal(v.size()).multiply(new BigDecimal(100))
					.divide(new BigDecimal(signUserList.size()), 2, RoundingMode.HALF_UP));
			result.add(salesData);
		});
		result.sort((SalesDataRespVO s1,SalesDataRespVO s2)->s2.getCount().compareTo(s1.getCount()));
		return result.stream().skip(0).limit(10).collect(Collectors.toList());
	}

	@Override
	public IPage<SignUserRespVo> getSignUserRankDetails(String startDate, String endDate, List<String> deptIds,
			Integer pageNum, Integer pageSize,String conditions) {
		IPage page = new Page();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		startDate = startDate + "-01";
		endDate = endDate + "-01";
		LocalDate startDateTemp = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		LocalDate endDateTemp = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		LocalDate lastDayOfMonth = endDateTemp.with(TemporalAdjusters.lastDayOfMonth());
		endDate = lastDayOfMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return page;
		}
		
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return page;
		}
		// 填充项目
		List<SysDictData> projectData = dictTypeService.selectDictDataByType("project_manage");
		for (SignUserRespVo signUserRespVo : signUserList) {
			SysDictData sysDictData = projectData.stream()
					.filter(e -> signUserRespVo.getDeptId().equals(e.getDictValue())).findAny().orElse(null);
			signUserRespVo.setDeptName(null == sysDictData ? null : sysDictData.getDictLabel());
		}
		
		//解析查询条件
		signUserList = this.parseSignParem(conditions,signUserList);

		signUserList.sort((SignUserRespVo v1, SignUserRespVo v2) -> {
			int compareTo = v2.getUserId().compareTo(v2.getUserId());
			if (0 == compareTo) {
				int compareTo2 = v2.getStartDate().compareTo(v1.getStartDate());
				if(0 == compareTo2) {
					return v2.getCustomerId().compareTo(v2.getCustomerId());
				}
				return compareTo2;
			}
			return compareTo;
		});

		List<SignUserRespVo> collect = signUserList.stream().skip((pageNum - 1) * pageSize).limit(pageSize)
				.collect(Collectors.toList());
		page.setRecords(collect);
		page.setCurrent(pageNum);
		page.setSize(pageSize);
		page.setTotal(signUserList.size());
		return page;
	}
	
	@Override
	public List<SignUserExcelDTO> getSignUserRankDetailsExport(String startDate, String endDate, List<String> deptIds,
			Integer pageNum, Integer pageSize,String conditions) {
		List<SignUserExcelDTO> result = new ArrayList<SignUserExcelDTO>();
		if (CollectionUtils.isEmpty(deptIds)) {
			deptIds = Arrays.asList(UserAndDeptUtils.getCurrentDeptId());
		}
		startDate = startDate + "-01";
		endDate = endDate + "-01";
		LocalDate startDateTemp = LocalDate.parse(startDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		LocalDate endDateTemp = LocalDate.parse(endDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		LocalDate lastDayOfMonth = endDateTemp.with(TemporalAdjusters.lastDayOfMonth());
		endDate = lastDayOfMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		// cp查询签约人员
		String resp = asyncService.getSignUserData(UserAndDeptUtils.getCurrentUserId(),UserAndDeptUtils.getCurrentDeptId(),startDate, endDate, deptIds);
		if (StringUtils.isBlank(resp)) {
			return result;
		}
		
		List<SignUserRespVo> signUserList = JSON.parseObject(resp).getList("data", SignUserRespVo.class);
		if (CollectionUtils.isEmpty(signUserList)) {
			return result;
		}
		
		// 填充项目
		List<SysDictData> projectData = dictTypeService.selectDictDataByType("project_manage");
		for (SignUserRespVo signUserRespVo : signUserList) {
			SysDictData sysDictData = projectData.stream()
					.filter(e -> signUserRespVo.getDeptId().equals(e.getDictValue())).findAny().orElse(null);
			signUserRespVo.setDeptName(null == sysDictData ? null : sysDictData.getDictLabel());
		}
		
		//解析查询条件
		signUserList = this.parseSignParem(null,signUserList);
		
		signUserList.sort((SignUserRespVo v1, SignUserRespVo v2) -> {
			int compareTo = v2.getUserId().compareTo(v2.getUserId());
			if (0 == compareTo) {
				int compareTo2 = v2.getStartDate().compareTo(v1.getStartDate());
				if(0 == compareTo2) {
					return v2.getCustomerId().compareTo(v2.getCustomerId());
				}
				return compareTo2;
			}
			return compareTo;
		});
		
		/*List<SignUserRespVo> collect = signUserList.stream().skip((pageNum - 1) * pageSize).limit(pageSize)
				.collect(Collectors.toList());*/
		return BeanUtil.toBeans(signUserList, SignUserExcelDTO.class);
	}
}
